package com.appistry.api.rest.impl;

import java.net.InetAddress;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpConnection;
import org.apache.commons.httpclient.SimpleHttpConnectionManager;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.appistry.api.rest.domain.Credentials;
import com.appistry.api.rest.httpcommons.FabricManagerHttpMethodRetryHandler;

public class HttpRestConnection extends AbstractRestConnection {
	private static final Log LOG = LogFactory.getLog(HttpRestConnection.class);
	private static final String PROTOCOL = "http";
	private Credentials credentials;
	private InetAddress address;
	private int port;

	private FabricManagerHttpMethodRetryHandler retryHandler;
	private long connectionTimeout = -1;

	@Deprecated
	public HttpRestConnection(InetAddress address, int port, String username, String password, int retryCount, long retryDelay, long connectionTimeout) {
		this(address, port);
		this.credentials = new Credentials(username, password);
		this.retryHandler = new FabricManagerHttpMethodRetryHandler(retryCount, retryDelay);
		this.connectionTimeout = connectionTimeout;
	}

	public HttpRestConnection(InetAddress address, int port, Credentials credentials) {
		this(address, port);
		this.credentials = credentials;
	}

	public HttpRestConnection(InetAddress address, Credentials credentials) {
		this(address);
		this.credentials = credentials;
	}

	public HttpRestConnection(InetAddress address, int port) {
		this(address);
		this.port = port;
	}

	public HttpRestConnection(InetAddress address) {
		if (address == null) {
			throw new RuntimeException("Host can't be null!");
		}
		this.address = address;

		// Set default port to 80
		this.port = 80;
	}

	@Override
	protected HttpClient getHttpClient() {

		// Create HttpClient that releases connections
		HttpClient client = new HttpClient(new SimpleHttpConnectionManager() {
			@Override
			public void releaseConnection(HttpConnection conn) {
				if (conn == null) {
					return;
				}
				conn.close();

				super.releaseConnection(conn);
			}
		});

		// Set host using HTTP protocol
		client.getHostConfiguration().setHost(address.getHostAddress(), port, PROTOCOL);

		// Add any credentials
		if (credentials != null) {
			// use custom retry handler
			if (retryHandler != null) {
				client.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, retryHandler);
			}
			if (connectionTimeout != -1) {
				client.getParams().setConnectionManagerTimeout(connectionTimeout);
			}

			client.getParams().setAuthenticationPreemptive(true);
			client.getState().setCredentials(new AuthScope(address.getHostAddress(), port), new UsernamePasswordCredentials(credentials.getUser(), credentials.getPassword()));
		}

		return client;
	}

}
